﻿Imports System.IO

'****************************************************************************************
'*** NOTE: THERE ARE TWO LISTBOXS HIDDEN BEHIND THE VISIBLE ONE.                     ****
'***       THESE LISTS HOLD THE ACTUAL PATHS.  I THOUGHT THIS WAS THE EASIEST WAY TO ****
'***       MANIPULATE THE PATH INFORMATION SINCE IT WOULD MORE EASILY MATCH HOW THE  ****
'***       PATH TAGS WERE BEING HANDLED.  MANIPULATION OF THE HIDDEN LIST IS PRETTY  ****
'***       MUCH IDENTICAL TO THE VISIBLE LIST, WITH A TWEAK OR TWO SINCE SOME CODE   ****
'***       FOR THE VISIBLE LIST WORKS FROM PHYSICAL CLICKS.                          ****
'****************************************************************************************

Public Class frmFolderPad
    'Const CtrlMask = 8
    Dim pathNames As String 'HOLDS THE TAGS IN MEMORY FROM THE DATA FILE OF EACH ENTRY
    Dim pathStrings As String 'HOLDS THE PATHS IN MEMORY FROM THE DATA FILE OF EACH ENTRY
    Dim uncStrings As String 'HOLDS THE UNC PATHS IN MEMORY FROM THE DATA FILE OF EACH ENTRY

    Private Sub folderList_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles folderList.DoubleClick
        AccessFolder()
    End Sub

    Private Sub folderList_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles folderList.KeyDown
        If e.KeyCode = Keys.Enter Then
            AccessFolder()
        End If
    End Sub

    Private Sub mnuOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuOpen.Click
        AccessFolder()
    End Sub

    Private Sub AccessFolder()
        Dim pathString As String = ""

        If folderList.Items.Count = 0 Or folderList.SelectedIndex = -1 Then
            'CAUSES A DOUBLECLICK ON THE LIST TO PULL UP THE FOLDERBROWSER IF THE LIST IS
            'EMPTY OR NO ITEM IS SELECTED
            browseFolders(0)
        Else
            'LAUNCHES THE PATH OF THE SELECTED TAG IN EXPLORER.EXE
            pathString = txtPath.Text

            Process.Start("explorer.exe", pathString)
            FolderPad.Hide()
        End If
    End Sub

    Private Sub mnuAddMapped_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuAddMapped.Click
        browseFolders(0)
    End Sub

    Private Sub mnuAddCustom_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuAddCustom.Click
        browseFolders(1)
    End Sub

    Private Sub browseFolders(ByVal type As Integer) 'USED TO SELECT FOLDER PATH
        Dim pathString As String
        Dim pathName As String

        If type = 0 Then
            If FolderBrowseDiag.ShowDialog() = Windows.Forms.DialogResult.OK Then
                pathString = FolderBrowseDiag.SelectedPath
                pathName = InputBox("Choose a label for: " + pathString, "Path Title", pathString)

                If pathName <> vbNullString Then
                    folderList.Items.Add(pathName)
                    pathList.Items.Add(pathString)
                    uncList.Items.Add(ConvertToUncPath(pathString))

                    populateVar()
                Else
                    MessageBox.Show("No Tag was specified.  Folder not Added.", "Add Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop)
                End If
            End If
        ElseIf type = 1 Then
            frmCustomChoice.ShowDialog()

            If Not frmCustomChoice.DialogResult = DialogResult.Cancel Then
                If Not Directory.Exists(customPath) Then
                    MessageBox.Show(customPath + " is not a valid path, or you do not have permission to access it.", "Path Error", MessageBoxButtons.OK)
                Else
                    folderList.Items.Add(customTag)
                    pathList.Items.Add(customPath)
                    uncList.Items.Add(ConvertToUncPath(customPath))

                    populateVar()
                End If
            End If
        End If
    End Sub

    Private Sub mnuRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuRemove.Click
        If folderList.SelectedIndex = -1 Then 'CHECKS IF AN ITEM IS SELECTED
            MessageBox.Show("Please choose an entry to Remove.", "Delete Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop)
        Else
            'IF THERE IS AN ITEM SELECTED A CONFIRMATION OF DELETION APPEARS
            'AND IT IS DELETED AND VARIABLES, TEXT FILES AND LISTS ARE REPOPULATED
            If MessageBox.Show("Are you sure you want to remove: " + folderList.SelectedItem.ToString + "?", "Removing Entry", MessageBoxButtons.YesNo, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
                pathList.Items.RemoveAt(folderList.SelectedIndex)
                uncList.Items.RemoveAt(folderList.SelectedIndex)
                folderList.Items.Remove(folderList.SelectedItem)

                populateVar()
            End If
        End If
    End Sub

    Private Sub mnuRename_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuRename.Click
        Renamer("tag")
    End Sub

    Private Sub mnuPath_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuPath.Click
        Renamer("path")
    End Sub

    Private Sub Renamer(ByVal type As String)
        Dim pathName As String

        If type = "tag" Then
            If folderList.SelectedIndex = -1 Then 'CHECKS IF AN ITEM IS SELECTED
                MessageBox.Show("Please choose an entry to Rename.", "Rename Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop)
            Else
                'IF THERE IS AN ITEM SELECTED AN INPUT BOX TO RENAME APPEARS
                'AND IT IS RENAMED AND VARIABLES, TEXT FILES AND LISTS ARE REPOPULATED
                pathName = InputBox("Choose a new Tag for: " + folderList.Items(folderList.SelectedIndex).ToString, "Path Title Renaming", folderList.Items(folderList.SelectedIndex).ToString)

                If pathName <> vbNullString Then

                    folderList.Items.Insert(folderList.SelectedIndex, pathName)
                    folderList.Items.RemoveAt(folderList.SelectedIndex)

                    populateVar()
                End If
            End If
        ElseIf type = "path" Then
            If folderList.SelectedIndex = -1 Then 'CHECKS IF AN ITEM IS SELECTED
                MessageBox.Show("Please choose an entry to Edit.", "Edit Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop)
            Else
                'IF THERE IS AN ITEM SELECTED AN INPUT BOX TO RENAME APPEARS
                'AND IT IS RENAMED AND VARIABLES, TEXT FILES AND LISTS ARE REPOPULATED
                pathName = InputBox("Edit the Path for: " + folderList.Items(folderList.SelectedIndex).ToString, "Path Title Renaming", pathList.Items(folderList.SelectedIndex).ToString)

                If pathName <> vbNullString Then

                    pathList.Items.Insert(folderList.SelectedIndex, pathName)
                    pathList.Items.RemoveAt(folderList.SelectedIndex + 1)
                    uncList.Items.Insert(folderList.SelectedIndex, ConvertToUncPath(pathName))
                    uncList.Items.RemoveAt(folderList.SelectedIndex + 1)

                    populateVar()
                End If
            End If
        End If
    End Sub

    Private Sub folderList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles folderList.SelectedIndexChanged
        buttonCheck()

        pathList.SelectedIndex = folderList.SelectedIndex

        If folderList.SelectedIndex <> -1 Then
            If My.Settings.uncEnabled = 0 Then
                txtPath.Text = pathList.Items(folderList.SelectedIndex)
            ElseIf My.Settings.uncEnabled = 1 Then
                txtPath.Text = uncList.Items(folderList.SelectedIndex)
            End If
        End If
    End Sub

    Private Sub buttonCheck()
        'CHECKS CURRENT SELECTION SO THAT BUTTONS ARE DISABLED
        'IF CURRENT SELECTION IS THE FIRST OR LAST ELEMENT
        If folderList.Items.Count = 0 Then
            btnUp.Enabled = False
            btnDown.Enabled = False
        End If

        If folderList.SelectedIndex = 0 Then
            btnUp.Enabled = False
        Else
            btnUp.Enabled = True
        End If

        If folderList.SelectedIndex = folderList.Items.Count - 1 Then
            btnDown.Enabled = False
        Else
            btnDown.Enabled = True
        End If
    End Sub

    Private Sub frmFolderPad_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        If e.CloseReason <> CloseReason.WindowsShutDown Then
            e.Cancel = True
            Me.Hide()
        End If
    End Sub

    Private Sub frmFolderPad_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'CODE TO FORCE ADD A DATA BINDING FOR foldersize AND folderlocation
        Me.DataBindings.Add("Size", My.Settings, "foldersize", True, DataSourceUpdateMode.OnPropertyChanged)
        Me.DataBindings.Add("Location", My.Settings, "folderlocation", True, DataSourceUpdateMode.OnPropertyChanged)

        If Not System.IO.File.Exists(savePath & "padfolder.txt") Then
            writeFile() 'CREATES A FOLDERPAD TEXT AS IT IS NEEDED UPON LOAD
        End If

        populateList()

        If folderList.Items.Count = 1 And folderList.Items(0).ToString = "" Then
            'WHEN READING INFORMATION FROM A TEXT FILE, AN 'ENTRY' IS CREATED EVEN IF THE 
            'THE FILE IS EMPTY.  TO AVOID THIS, THE 'EMPTY' ELEMENT IS REMOVED FROM THE LIST
            'SO THERE CAN BE NO GHOST ENTRIES AND NO ACTIONS PERFORMED ON AN 'EMPTY' ELEMENT.
            folderList.Items.RemoveAt(0)
            pathList.Items.RemoveAt(0)
            uncList.Items.RemoveAt(0)
        End If
    End Sub

    Private Sub populateList()
        readFile()

        'INCOMING STRINGS ARE USING A PIPE DELIMITER (EASIER THAN INI STYLE FILES FOR SAVING DATA)
        Dim namesArray() As String = Split(pathNames, "|")
        Dim pathsArray() As String = Split(pathStrings, "|")
        Dim uncArray() As String = Split(uncStrings, "|")

        folderList.Items.Clear()
        pathList.Items.Clear()
        uncList.Items.Clear()

        'INSERTS ITEMS INTO RESPECTIVE LISTS
        For i As Integer = 0 To pathsArray.Length - 1 Step 1
            folderList.Items.Add(namesArray(i)) 'FOLDER TAGS
            pathList.Items.Add(pathsArray(i)) 'FOLDER PATHS
            uncList.Items.Add(uncArray(i)) 'UNC PATHS
        Next i
    End Sub

    Private Sub populateVar() 'REPOPULATES RESPECTIVE VARIABLES WITH CURRENT ITEMS IN LISTS
        pathNames = ""
        pathStrings = ""
        uncStrings = ""

        For i As Integer = 0 To folderList.Items.Count - 1
            If i <> folderList.Items.Count - 1 Then
                pathNames += (folderList.Items(i).ToString + "|")
                pathStrings += (pathList.Items(i).ToString + "|")
                uncStrings += (uncList.Items(i).ToString + "|")
            Else
                pathNames += folderList.Items(i).ToString
                pathStrings += pathList.Items(i).ToString
                uncStrings += uncList.Items(i).ToString
            End If
        Next i

        writeFile()
        populateList()
    End Sub

    Private Sub readFile()
        Dim readstring As New StreamReader(savePath & "padfolder.txt")
        readstring.BaseStream.Seek(0, SeekOrigin.Begin)
        Dim counter As Integer

        While readstring.Peek > -1
            Select Case counter
                Case 1
                    pathNames = readstring.ReadLine() 'LINE 1 OF TEXT FILE
                Case 2
                    pathStrings = readstring.ReadLine() 'LINE 2 OF TEXT FILE
                Case 3
                    uncStrings = readstring.ReadLine() 'LINE 3 OF TEXT FILE
            End Select
            counter += 1
        End While

        readstring.Close()
        readstring.Dispose()
    End Sub

    Private Sub writeFile()
        Dim writestring As New StreamWriter(savePath & "padfolder.txt", False)

        writestring.WriteLine(pathNames)
        writestring.WriteLine(pathStrings)
        writestring.WriteLine(uncStrings)

        writestring.Close()
        writestring.Dispose()
    End Sub

    Private Sub btnUp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUp.Click
        If folderList.SelectedIndex <> -1 Then
            'MOVES THE ITEM UP IN THE LIST
            'THIS FUNCTION INTERACTS WITH A SECOND HIDDEN LIST TO KEEP TRACK OF 
            'FOLDER PATHS AS WELL.  EASIER TO MANIPULATE THAN ONE SET IN A LIST AND THE 
            'OTHER IN A VARIABLE
            Dim i As Integer = folderList.SelectedIndex - 1
            Dim flname As String = folderList.Items(i).ToString
            Dim plname As String = pathList.Items(i).ToString
            Dim uncname As String = uncList.Items(i).ToString

            If i + 2 = folderList.Items.Count Then
                folderList.Items.Add(flname)
                pathList.Items.Add(plname)
                uncList.Items.Add(uncname)
            Else
                folderList.Items.Insert(i + 2, flname)
                pathList.Items.Insert(i + 2, plname)
                uncList.Items.Insert(i + 2, uncname)
            End If
            folderList.Items.RemoveAt(i)
            pathList.Items.RemoveAt(i)
            uncList.Items.RemoveAt(i)

            Dim flx As Integer = folderList.SelectedIndex
            Dim plx As Integer = pathList.SelectedIndex
            Dim uncx As Integer = uncList.SelectedIndex

            buttonCheck()
            populateVar()

            folderList.SelectedIndex = flx
            pathList.SelectedIndex = plx
            uncList.SelectedIndex = uncx
        End If
    End Sub

    Private Sub btnDown_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDown.Click
        If folderList.SelectedIndex <> -1 Then
            'MOVES THE ITEM DOWN IN THE LIST
            'THIS FUNCTION INTERACTS WITH A SECOND HIDDEN LIST TO KEEP TRACK OF 
            'FOLDER PATHS AS WELL.  EASIER TO MANIPULATE THAT ONE SET IN A LIST AND THE 
            'OTHER IN A VARIABLE
            Dim i As Integer = folderList.SelectedIndex + 1
            Dim flname As String = folderList.Items(i).ToString
            Dim plname As String = pathList.Items(folderList.SelectedIndex + 1).ToString
            Dim uncname As String = uncList.Items(folderList.SelectedIndex + 1).ToString

            folderList.Items.Insert(i - 1, flname)
            folderList.Items.RemoveAt(i + 1)

            pathList.Items.Insert(i - 1, plname)
            pathList.Items.RemoveAt(i + 1)

            uncList.Items.Insert(i - 1, uncname)
            uncList.Items.RemoveAt(i + 1)

            Dim flx As Integer = folderList.SelectedIndex
            Dim plx As Integer = pathList.SelectedIndex
            Dim uncx As Integer = uncList.SelectedIndex

            buttonCheck()
            populateVar()

            folderList.SelectedIndex = flx
            pathList.SelectedIndex = plx
            uncList.SelectedIndex = uncx
        End If
    End Sub

    Private Sub txtPath_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPath.TextChanged
        'KEEPS USERS FROM MANIPULATING THE TEXTBOX THAT HOLDS THE PATH NAME
        'FOR COPY PURPOSES
        If folderList.SelectedIndex = -1 Then
            txtPath.Text = ""
        ElseIf My.Settings.uncEnabled = 0 Then
            txtPath.Text = pathList.Items(folderList.SelectedIndex)
        ElseIf My.Settings.uncEnabled = 1 Then
            txtPath.Text = uncList.Items(folderList.SelectedIndex)
        End If
    End Sub

    Private Sub folderList_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles folderList.MouseDown
        Dim lb As ListBox = CType(sender, ListBox)
        Dim pt As New Point(e.X, e.Y)
        Dim index As Integer = lb.IndexFromPoint(pt)

        If e.Button = MouseButtons.Right Then
            If index >= 0 Then
                folderList.SelectedItem = folderList.Items.Item(index)
            ElseIf index = -1 Then
                folderList.ClearSelected()
                txtPath.Text = ""
            End If
            checkMenuStatus()
        End If

        If e.Button = MouseButtons.Left Then
            If index = -1 Then
                folderList.ClearSelected()
                txtPath.Text = ""
            End If
        End If
    End Sub

    Private Sub folderList_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles folderList.DragEnter
        If e.Data.GetDataPresent("FileNameW", True) Then
            e.Effect = DragDropEffects.All
        End If
    End Sub

    Private Sub folderList_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles folderList.DragOver
        Dim index As Integer = folderList.IndexFromPoint(folderList.PointToClient(New Point(e.X, e.Y)))

        If (index <> ListBox.NoMatches) Then
            folderList.SelectedIndex = index
        Else
            folderList.SelectedIndex = -1
        End If
    End Sub

    Private Sub checkMenuStatus()
        If folderList.SelectedIndex = -1 Then
            mnuOpen.Enabled = False
            mnuRemove.Enabled = False
            mnuRename.Enabled = False
            mnuPath.Enabled = False
        Else
            mnuOpen.Enabled = True
            mnuRemove.Enabled = True
            mnuRename.Enabled = True
            mnuPath.Enabled = True
        End If
    End Sub

    Private Sub tsbtnMyComputer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnMyComputer.Click
        Process.Start("explorer.exe", "/n,/select,c:")
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnMyDocuments_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnMyDocuments.Click
        Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments))
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnDesktop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnDesktop.Click
        Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.Desktop))
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnControlPanel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnControlPanel.Click
        Process.Start("control.exe")
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnProgramFiles_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnProgramFiles.Click
        Process.Start(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles))
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnAddRemovePrograms_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnAddRemovePrograms.Click
        Process.Start("appwiz.cpl")
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnNetworkProperties_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnNetworkProperties.Click
        Select Case Environment.OSVersion.Platform
            Case PlatformID.Win32Windows
                'WIN 98/ME - netcpl.cpl
                Process.Start("netcpl.cpl")
            Case PlatformID.Win32NT
                'NT4, XP, Vista, 7 - ncpa.cpl
                Process.Start("ncpa.cpl")
        End Select
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnPrinterFolder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnPrinterFolder.Click
        Process.Start("rundll32.exe", "shell32.dll,SHHelpShortcuts_RunDLL PrintersFolder")
        FolderPad.Hide()
    End Sub

    Private Sub tsbtnFontFolder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnFontFolder.Click
        Process.Start("rundll32.exe", "shell32.dll,SHHelpShortcuts_RunDLL FontsFolder")
        FolderPad.Hide()
    End Sub

    Public Function ConvertToUncPath(ByVal filePath As String) As String
        Dim driveLetter As String = System.IO.Path.GetPathRoot(filePath).Replace("\", "")
        Dim uncPath As String = driveLetter
        Dim query As New System.Management.ObjectQuery("select * from Win32_LogicalDisk")
        Using searcher As New System.Management.ManagementObjectSearcher(query)
            'loops for all drives on system
            For Each Mgmt As System.Management.ManagementObject In searcher.Get()
                'looks for drives with drivetype of 4 which is network drive
                If Mgmt("DriveType").ToString = "4" Then
                    If driveLetter = Mgmt("Caption").ToString Then
                        uncPath = Mgmt("ProviderName").ToString
                        Exit For
                    End If
                End If
            Next
        End Using
        Return filePath.Replace(driveLetter, uncPath)
    End Function

    ''Private Sub folderList_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles folderList.DragDrop
    ''    If e.Data.GetDataPresent("FileNameW", True) Then

    ''        Dim paths As System.Array = CType(e.Data.GetData(DataFormats.FileDrop), System.Array)
    ''        Dim strDestPath, strPath, strDest, strAction As String
    ''        Dim totalFiles As Integer = paths.Length

    ''        strDestPath = folderList.SelectedItem.ToString

    ''        If (e.KeyState And CtrlMask) = CtrlMask Then
    ''            strAction = "copy"
    ''        Else
    ''            strAction = "move"
    ''        End If

    ''        For i As Integer = 0 To totalFiles - 1 Step 1
    ''            strPath = paths(i)
    ''            strDest = IO.Path.Combine(strDestPath, IO.Path.GetFileName(strPath))

    ''            If strAction = "move" Then
    ''                If IO.File.GetAttributes(strPath) = IO.FileAttributes.Directory Then
    ''                    My.Computer.FileSystem.MoveDirectory(strPath, strDest, FileIO.UIOption.AllDialogs)
    ''                Else
    ''                    My.Computer.FileSystem.MoveFile(strPath, strDest, FileIO.UIOption.AllDialogs)
    ''                End If
    ''            ElseIf strAction = "copy" Then
    ''                If IO.File.GetAttributes(strPath) = IO.FileAttributes.Directory Then
    ''                    My.Computer.FileSystem.CopyDirectory(strPath, strDest, FileIO.UIOption.AllDialogs)
    ''                Else
    ''                    My.Computer.FileSystem.CopyFile(strPath, strDest, FileIO.UIOption.AllDialogs)
    ''                End If
    ''            End If
    ''        Next
    ''    End If
    ''End Sub
End Class